package view;

import java.awt.Font;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.table.DefaultTableModel;
import org.jfree.chart.*;
import model.Input;

@SuppressWarnings("serial")
public class View extends JFrame {
	private JPanel contentPane;
	private JTextField tfPolynomial;
	private JTextField tfMaxIterations;
	private JTextField tfX1;
	private JTextField tfX2;
	private JTextField tfTolerance;
	private JTextField tfIterationNo;
	private JRadioButton rbRegulaFalsi;
	private JRadioButton rbSecant;
	private JTable tblAllIterations;
	private ChartPanel chrtIteration;
	private ChartPanel chrtAllIterations;
	private JSlider sldIteration;
	private JButton btnPrev;
	private JButton btnNext;
	private JButton btnSolve;
	
	private ArrayList<JFreeChart> charts;
	private int method;
	
	public View() {
		setResizable(false);
		initializeGUI();
		method = Input.REGULA_FALSI_METHOD;
	}
	
	public void setTblIterationsModel(DefaultTableModel model) {
		this.tblAllIterations.setModel(model);
	}
	
	public void setCharts(ArrayList<JFreeChart> charts){
		this.charts = charts;
		
		this.sldIteration.setMaximum(charts.size() - 1);
		this.sldIteration.setMinimum(0);
		this.sldIteration.setValue(0);
		showChart(0);
	}
	
	public void showChart(int index){
		if(charts.size() == 0){
			this.chrtIteration.setChart(null);
			return;
		}
		
		this.chrtIteration.setChart(charts.get(index));
		
		if(index == 0)
			this.tfIterationNo.setText("Base");
		else
			this.tfIterationNo.setText((index) + "/" + (charts.size()-1));
	}
	
	public Input getInput(){
		if(tfPolynomial.getText().trim().isEmpty() || tfX1.getText().trim().isEmpty() || tfX2.getText().trim().isEmpty()){
			JOptionPane.showMessageDialog(null, "Please fill up the Polynomial, X1 and X2 input fields", "Error", JOptionPane.ERROR_MESSAGE);
        	return null;	
		}

		int max;
		
		if(this.tfMaxIterations.getText().trim().isEmpty())
			max = 1000;
		else
			max = Integer.parseInt(tfMaxIterations.getText());
		
		double tol;
		if(this.tfTolerance.getText().trim().isEmpty())
			tol = 0;
		else
			tol = Double.parseDouble(tfTolerance.getText());
		
		return new Input(tfPolynomial.getText(),Double.parseDouble(tfX1.getText()),Double.parseDouble(tfX2.getText()), 
				method, max, tol);
	}
	
	public void addBtnSolve(ActionListener listener){
		addButtonListener(btnSolve, listener);
	}
	
	private void addButtonListener(JButton button, ActionListener listener){
		if(button != null && listener != null){
			if(button.getActionListeners().length > 0)
				button.removeActionListener(button.getActionListeners()[0]);
			
			button.addActionListener(listener);
		}
	}

	public void setXChart(JFreeChart xChart) {
		this.chrtAllIterations.setChart(xChart);
	}
	
	public void initializeGUI() {
		setTitle("ADVSTAT Project 2");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 1200, 550);
		contentPane = new JPanel();
		contentPane.setBackground(UIManager.getColor("Panel.background"));
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		JPanel pnlInput = new JPanel();
		pnlInput.setBorder(new TitledBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null), "Input", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		pnlInput.setBounds(10, 11, 1174, 131);
		contentPane.add(pnlInput);
		pnlInput.setLayout(null);
		
		tfPolynomial = new JTextField();
		tfPolynomial.setColumns(10);
		tfPolynomial.setBounds(29, 43, 241, 20);
		pnlInput.add(tfPolynomial);
		
		tfX1 = new JTextField();
		tfX1.setColumns(10);
		tfX1.setBounds(29, 99, 86, 20);
		pnlInput.add(tfX1);
		
		tfX2 = new JTextField();
		tfX2.setColumns(10);
		tfX2.setBounds(184, 99, 86, 20);
		pnlInput.add(tfX2);
		
		rbRegulaFalsi = new JRadioButton("Regula-Falsi");
		rbRegulaFalsi.setSelected(true);
		rbRegulaFalsi.setFont(new Font("Consolas", Font.PLAIN, 12));
		rbRegulaFalsi.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				rbSecant.setSelected(false);
				method = Input.REGULA_FALSI_METHOD;
			}
		});
		rbRegulaFalsi.setBounds(317, 42, 120, 23);
		pnlInput.add(rbRegulaFalsi);
		
		rbSecant = new JRadioButton("Secant");
		rbSecant.setFont(new Font("Consolas", Font.PLAIN, 12));
		rbSecant.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				rbRegulaFalsi.setSelected(false);
				method = Input.SECANT_METHOD;
			}
		});
		rbSecant.setBounds(455, 43, 98, 23);
		pnlInput.add(rbSecant);
		
		tfMaxIterations = new JTextField();
		tfMaxIterations.setColumns(10);
		tfMaxIterations.setBounds(465, 99, 86, 20);
		pnlInput.add(tfMaxIterations);
		
		tfTolerance = new JTextField();
		tfTolerance.setColumns(10);
		tfTolerance.setBounds(317, 99, 86, 20);
		pnlInput.add(tfTolerance);

		btnSolve = new JButton("Solve");
		btnSolve.setFont(new Font("Consolas", Font.PLAIN, 99));
		btnSolve.setBounds(609, 18, 555, 103);
		pnlInput.add(btnSolve);
		
		JLabel lblPolynomial = new JLabel("Polynomial");
		lblPolynomial.setFont(new Font("Consolas", Font.PLAIN, 12));
		lblPolynomial.setBounds(19, 18, 86, 14);
		pnlInput.add(lblPolynomial);
		
		JLabel lblX1 = new JLabel("x1");
		lblX1.setFont(new Font("Consolas", Font.PLAIN, 12));
		lblX1.setBounds(19, 74, 46, 14);
		pnlInput.add(lblX1);
		
		JLabel lblX2 = new JLabel("x2");
		lblX2.setFont(new Font("Consolas", Font.PLAIN, 12));
		lblX2.setBounds(174, 74, 46, 14);
		pnlInput.add(lblX2);
		
		JLabel lblMaxIterations = new JLabel("Max No. of Iterations");
		lblMaxIterations.setFont(new Font("Consolas", Font.PLAIN, 12));
		lblMaxIterations.setBounds(455, 73, 155, 14);
		pnlInput.add(lblMaxIterations);
		
		JLabel lblTolerance = new JLabel("Tolerance");
		lblTolerance.setFont(new Font("Consolas", Font.PLAIN, 12));
		lblTolerance.setBounds(307, 74, 106, 14);
		pnlInput.add(lblTolerance);
		
		JLabel lblMethod = new JLabel("Method");
		lblMethod.setFont(new Font("Consolas", Font.PLAIN, 12));
		lblMethod.setBounds(307, 18, 46, 14);
		pnlInput.add(lblMethod);
		
		JPanel pnlOutput = new JPanel();
		pnlOutput.setBorder(new TitledBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null), "Output", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		pnlOutput.setBounds(10, 153, 1174, 360);
		contentPane.add(pnlOutput);
		pnlOutput.setLayout(null);
		
		chrtIteration = new ChartPanel((JFreeChart) null);
		chrtIteration.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		chrtIteration.setMouseWheelEnabled(true);
		chrtIteration.setBounds(713, 24, 451, 289);
		pnlOutput.add(chrtIteration);
		
		btnPrev = new JButton("Prev");
		btnPrev.setFont(new Font("Consolas", Font.PLAIN, 12));
		btnPrev.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if(sldIteration.getValue() > 0){
					showChart(sldIteration.getValue() - 1);
					sldIteration.setValue(sldIteration.getValue() - 1);
				}
			}
		});
		btnPrev.setBounds(713, 325, 61, 23);
		pnlOutput.add(btnPrev);
		
		sldIteration = new JSlider();
		sldIteration.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				JSlider source = (JSlider)e.getSource();
			    if (!source.getValueIsAdjusting()) 
			    	showChart(source.getValue());  
			    }
		});
		sldIteration.setBounds(853, 325, 240, 23);
		pnlOutput.add(sldIteration);
		
		btnNext = new JButton("Next");
		btnNext.setFont(new Font("Consolas", Font.PLAIN, 12));
		btnNext.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(sldIteration.getValue() < sldIteration.getMaximum()){
					showChart(sldIteration.getValue() + 1);
					sldIteration.setValue(sldIteration.getValue() + 1);
				}
			}
		});
		btnNext.setBounds(1103, 325, 61, 23);
		pnlOutput.add(btnNext);
		
		tfIterationNo = new JTextField();
		tfIterationNo.setEnabled(false);
		tfIterationNo.setFont(new Font("Consolas", Font.PLAIN, 12));
		tfIterationNo.setBounds(784, 326, 61, 20);
		pnlOutput.add(tfIterationNo);
		tfIterationNo.setColumns(10);
		
		JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
		tabbedPane.setBounds(10, 24, 693, 324);
		pnlOutput.add(tabbedPane);
		
		chrtAllIterations = new ChartPanel((JFreeChart) null);
		chrtAllIterations.setMouseWheelEnabled(true);
		chrtAllIterations.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		tabbedPane.addTab("Chart", null, chrtAllIterations, null);
		
		JScrollPane scrollPane = new JScrollPane();
		tabbedPane.addTab("Table", null, scrollPane, null);
		
		tblAllIterations = new JTable();
		tblAllIterations.setFont(new Font("Calibri", Font.PLAIN, 12));
		scrollPane.setViewportView(tblAllIterations);
		
		setLocationRelativeTo(null);
		this.setVisible(true);
	}
}
